/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 *
 * The information contained herein is confidential property of Nordic
 * Semiconductor ASA.Terms and conditions of usage are described in detail
 * in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 *
 * Licensees are granted free, non-transferable use of the information. NO
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 * the file.
 *
 * $$
 */

#include "ble_app_gzll_ui.h"
#include <stdint.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf_soc.h"
#include "nrf_assert.h"
#include "nrf_gpio.h"
#include "ble_sdk_util.h"


void leds_init(void)
{
    GPIO_LED_CONFIG(ADVERTISING_LED_PIN_NO);
    GPIO_LED_CONFIG(CONNECTED_LED_PIN_NO);
    GPIO_LED_CONFIG(ASSERT_LED_PIN_NO);
    GPIO_LED_CONFIG(GZLL_TX_SUCCESS_LED_PIN_NO);
    GPIO_LED_CONFIG(GZLL_TX_FAIL_LED_PIN_NO);
}


void GPIOTE_IRQHandler(void)
{
    if (
        (NRF_GPIOTE->EVENTS_PORT != 0)
        &&
        ((NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_PORT_Msk) != 0)
    )
    {
        NRF_GPIOTE->EVENTS_PORT = 0;
        
        if (nrf_gpio_pin_read(BLE_BUTTON_PIN_NO) == 0)  // BLE Button
        {
            running_proprietary_mode = false;
        }
        if (nrf_gpio_pin_read(GZLL_BUTTON_PIN_NO) == 0) // GZLL Button
        {
            running_proprietary_mode = true;
        }
    }
}


void buttons_init(void)
{
    uint32_t err_code;
    uint32_t per_rdy;
    
    // Power on GPIOTE module
    if (running_proprietary_mode)
    {
        NRF_POWER->PERPOWER |=(POWER_PERPOWER_GPIOTE_Msk);
        do
        {
            per_rdy = NRF_POWER->PERRDY;
        } while ((per_rdy & POWER_PERRDY_GPIOTE_Msk) == 0);
    }
    else
    {
        err_code = nrf_power_perpower_set(POWER_PERPOWER_GPIOTE_Msk);
        if (err_code != NRF_SUCCESS)
        {
            ASSERT(false);
        }
        do
        {
            err_code = nrf_power_perrdy_get(&per_rdy);
            if (err_code != NRF_SUCCESS)
            {
                ASSERT(false);
            }
        } while ((per_rdy & POWER_PERRDY_GPIOTE_Msk) == 0);
    }
    
    // Initialize GPIOTE module
    NRF_GPIOTE->INTENCLR = 0xffffffffUL;
    NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk;
    
    // Set all used buttons as wakeup source (Buttons 0-1)
    NRF_GPIO->PIN_CNF[BLE_BUTTON_PIN_NO] =
                                          (GPIO_PIN_CNF_DIR_Input     << GPIO_PIN_CNF_DIR_Pos)    |
                                          (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)  |
                                          (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)   |
                                          (GPIO_PIN_CNF_DRIVE_S0S1    << GPIO_PIN_CNF_DRIVE_Pos)  |
                                          (GPIO_PIN_CNF_SENSE_Low     << GPIO_PIN_CNF_SENSE_Pos);
    
    NRF_GPIO->PIN_CNF[GZLL_BUTTON_PIN_NO] =
                                          (GPIO_PIN_CNF_DIR_Input     << GPIO_PIN_CNF_DIR_Pos)    |
                                          (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)  |
                                          (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)   |
                                          (GPIO_PIN_CNF_DRIVE_S0S1    << GPIO_PIN_CNF_DRIVE_Pos)  |
                                          (GPIO_PIN_CNF_SENSE_Low     << GPIO_PIN_CNF_SENSE_Pos);
                                          
    // Enable GPIOTE interrupt
    if (running_proprietary_mode)
    {
        NVIC_ClearPendingIRQ(GPIOTE_IRQn);
        NVIC_SetPriority(GPIOTE_IRQn, NRF_APP_PRIORITY_LOW);
        NVIC_EnableIRQ(GPIOTE_IRQn);
    }
    else
    {
        err_code = nrf_nvic_ClearPendingIRQ(GPIOTE_IRQn);
        if (err_code != NRF_SUCCESS)
        {
            ASSERT(false);
        }
        
        err_code = nrf_nvic_SetPriority(GPIOTE_IRQn, NRF_APP_PRIORITY_LOW);
        if (err_code != NRF_SUCCESS)
        {
            ASSERT(false);
        }
        
        err_code = nrf_nvic_EnableIRQ(GPIOTE_IRQn);
        if (err_code != NRF_SUCCESS)
        {
            ASSERT(false);
        }
    }
}
